<!--
    * Time    : 2021-02-23 14:55:29
    * Author  : zhangTj
    * Desc    : 拖拽上传图片
-->

<template>
    <div>
        <vuedraggable v-model="uploadList" :delay="delay" filter=".upload-img" animation="1000" class="drag-wrap">
            <transition-group>
                <div v-for="(item, index) in uploadList" :key="item" class="position-relative">
                    <div class="border-dashed m-0-auto" style="width: 2rem; height: 2rem; border-color: #ddd">
                        <img @click="previewPic(index)" :src="$imgUrlHead + item" alt="" class="w-100 h-100" style="object-fit: contain" />
                    </div>
                    <div class="position-absolute bottom-0 left-0 text-center w-100 text-fff" style="background: rgba(149, 149, 149, 0.8)">
                        <p class="font-14">
                            更换
                            <input
                                :id="`input${index}`"
                                :ref="`input${index}`"
                                type="file"
                                name="files"
                                accept="image/*"
                                class="imgUpload"
                                @change="changeImg($event, index)"
                            />
                        </p>
                    </div>
                    <div @click="delImg(index)" class="position-absolute" style="top: -9px; right: -9px; width: 20px; height: 20px; z-index: 10">
                        <img class="w-100 h-100" src="@/assets/images/close1.png" alt="" />
                    </div>
                </div>

                <!-- 这个上传input必须加一个key，用于锁定上传 -->
                <div
                    v-if="uploadList && uploadList.length < limit"
                    :key="999"
                    class="position-relative border-dashed rounded-5 position-relative d-inline-block upload-img"
                    style="width: 2rem; height: 2rem; border-color: #ddd"
                >
                    <input id="input" ref="input" type="file" name="files" accept="image/*" class="imgUpload" @change="uploadImg($event)" />
                    <span class="iconfont iconadd text-ddd position-absolute" style="top: 50%; left: 50%; transform: translate(-50%, -50%)"></span>
                </div>
            </transition-group>
        </vuedraggable>
    </div>
</template>

<script>
import vuedraggable from 'vuedraggable'
import uploadFile from 'utils/uploadimg'
import { ImagePreview } from 'vant'

export default {
    name: 'DragUpload',
    components: { vuedraggable },
    props: {
        value: {
            type: Array
        },
        limit: {
            type: Number,
            default: 5
        },
        delay: {
            type: Number,
            default: 0
        },
        // 最少保存n张图片, 0时不限制
        retain: {
            type: Number,
            default: 0
        }
    },
    data() {
        return {
            uploadList: [] // 数组
        }
    },
    computed: {},
    watch: {
        value: {
            immediate: true,
            handler(newVal) {
                // 如果传入一个字符串，则转为一个数组
                if (typeof newVal === 'string') {
                    this.uploadList = []
                } else {
                    this.uploadList = newVal
                }
            }
        },
        uploadList: {
            handler(newVal) {
                this.$emit('input', newVal)
            }
        }
    },
    methods: {
        // 上传图片
        async uploadImg(event) {
            const filesList = event.target.files

            this.$toast.loading({
                message: '上传中...',
                duration: 0
            })
            try {
                let result = await uploadFile(filesList[0])
                if (!result.success) {
                    this.$toast(result.msg)
                    return
                }
                this.uploadList.push(result.photos)
                this.$toast('上传成功')
                this.$refs.input.value = null // 必须清空input框里面的值，不然change事件对同一张图片不起作用
                this.$nextTick(() => {
                    this.$emit('success', result.photos)
                })
            } catch (error) {
                this.$toast(error.msg)
                this.$emit('fail', error)
            }
        },

        // 预览图片
        previewPic(picIndex) {
            ImagePreview({
                images: this.uploadList.map((item) => this.$imgUrlHead + item),
                startPosition: picIndex
            })
        },

        // 更换图片
        async changeImg(event, index) {
            const filesList = event.target.files

            this.$toast.loading({
                message: '上传中...',
                duration: 0
            })

            try {
                let result = await uploadFile(filesList[0])
                if (!result.success) {
                    this.$toast(result.msg)
                    return
                }
                this.$set(this.uploadList, index, result.photos)
                this.$toast('更换成功')
                this.$refs[`input${index}`].value = null // 必须清空input框里面的值，不然change事件对同一张图片不起作用
                this.$nextTick(() => {
                    this.$emit('changeSuc', result.photos)
                })
            } catch (error) {
                this.$toast(error.msg)
                this.$emit('changeFail', error)
            }
        },

        // 删除图片
        delImg(index) {
            if (this.retain && this.uploadList.length == this.retain) {
                this.$toast('至少保留一张图片')
                return
            }
            this.uploadList.splice(index, 1)
            this.$toast('删除成功')
            this.$nextTick(() => {
                this.$emit('delSuc', this.uploadList)
            })
        }
    }
}
</script>

<style scoped>
.imgUpload {
    position: absolute;
    right: 0;
    top: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
}
.drag-wrap span:first-child {
    display: grid;
    grid-gap: 20px;
    grid-template-columns: repeat(3, 1fr);
}
</style>
